﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using courseProjectV1.Models;
using courseProjectV1.Db;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography;
using System.Text;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;

namespace courseProjectV1.Controllers
{
    public class AccountController : Controller
    {
        private DataBaseContext _context;
        public AccountController(DataBaseContext context)
        {
            this._context = context;
        }
        [HttpGet]
        public IActionResult SignIn()
        {
            return View();
        }
        [HttpGet]
        public IActionResult SignUp()
        {
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> SignIn(SignInModel model)
        {
            if (ModelState.IsValid)
            {
                model.Password = encode(model.Password);
                User? user = await _context.Users.Include(p=>p.Role).FirstOrDefaultAsync(p => p.Login == model.Login && p.Password == model.Password);
                if(user != null)
                {
                    Authenticate(model.Login,user.Role.Name);
                    return RedirectToAction("Index", "Home");
                }
                ModelState.AddModelError("", "Login or password is not correct!");
            }
            return View(model);
        }
        [HttpPost]
        public async Task<IActionResult> SignUp(SignUpModel model)
        {
            if (ModelState.IsValid)
            {
                User? user = await _context.Users.FirstOrDefaultAsync(p => p.Login == model.Login);
                if(user == null)
                {
                    user = new User();
                    model.Password = encode(model.Password);
                    user.Login = model.Login;
                    user.Password = model.Password;
                    user.Role = await _context.Roles.FirstOrDefaultAsync(p => p.Name == "Client");
                    await _context.Users.AddAsync(user);
                    await _context.SaveChangesAsync();
                    Authenticate(model.Login,user.Role.Name);
                    return RedirectToAction("Index", "Home");
                }
                ModelState.AddModelError("", "This login is already used!");
            }
            return View(model);
        }
        [HttpGet]
        public async Task<IActionResult> SignOut()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return RedirectToAction("SignIn", "Account");
        }
        private async void Authenticate(string login,string role)
        {
            List<Claim> claims = new List<Claim>()
            {
                new Claim(ClaimsIdentity.DefaultNameClaimType,login),
                new Claim(ClaimsIdentity.DefaultRoleClaimType,role),
            };
            ClaimsIdentity id = new ClaimsIdentity(claims, "ApplicationCookie", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(id));
        }
        public static string encode(string value)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value));
            byte[] res = md5.Hash;
            value = "";
            foreach (var i in res)
            {
                value += i.ToString("x2");
            }
            return value;
        }
    }
}

